package br.ita.trucocearense.server.core.remote;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;

import br.ita.trucocearense.common.core.interfaces.remote.JogoRemoto;
import br.ita.trucocearense.common.core.interfaces.remote.padraoobserver.RemoteObserver;
import br.ita.trucocearense.common.core.interfaces.remoteobjects.ObjCarta;
import br.ita.trucocearense.server.core.Carta;
import br.ita.trucocearense.server.core.DeckCartas;
import br.ita.trucocearense.server.core.Jogo;
import br.ita.trucocearense.server.core.Mesa;
import br.ita.trucocearense.server.core.remote.padraoobserver.RemoteSubjectImpl;

public class JogoRemotoImpl extends RemoteSubjectImpl implements JogoRemoto {
	private DeckCartas deck = new DeckCartas();
	private Jogo jogo;
	
	public JogoRemotoImpl() throws RemoteException {
	}


	public void iniciarJogo(Mesa mesa) throws RemoteException{
		this.jogo = new Jogo(mesa);
		this.jogo.iniciarPartida();
		notifyObservers("iniciarPartida");
	}
	
	public ObjCarta[] getCartasJogador(int posicao) throws RemoteException {				
		return this.jogo.getMesa().getUserPosicao(posicao).getCartas();
	}

	public int[] getPlacarJogo() throws RemoteException {
		int[] placar = new int[2];
		placar[0] = this.jogo.getMesa().getEquipe()[0].getPontuacaoJogo();
		placar[1] = this.jogo.getMesa().getEquipe()[1].getPontuacaoJogo();
		return placar;
		
	}

	public ObjCarta getManilha() throws RemoteException {
		return this.jogo.getPartida().getManilha();
	}

	public void baixarCartaJogadorDaVez(ObjCarta cartaCliente) throws RemoteException {
		Carta carta = new Carta(cartaCliente);
		System.out.println("Carta baixada " + carta.getCodigo() + " " + carta.getValorInteiro() + " ZAP " + carta.isZap() + "EPIAO " + carta.isEspiao());
		this.jogo.getPartida().getRodada().baixarCartaJogadorDaVez(carta);	
		notifyObservers("baixarCartaMesa");
		this.jogo.atualizarPlacar();
		
		
		if (this.jogo.isFinalDoJogo()){
			notifyObservers("terminarRodada");
			notifyObservers("terminarPartida",2000);
			notifyObservers("terminarJogo",4000);
			notifyObservers("voltaParaTelaSalaDeJogo",7000);
			this.jogo.getMesa().removeUsuariosMesa();
			return;
		}
		
		if (this.jogo.getPartida().isFinalDaPartida()){
			notifyObservers("terminarRodada");
			notifyObservers("terminarPartida",2000);
			this.jogo.iniciarPartida();
			notifyObservers("iniciarPartida",3000);
			return;
		}
		
		if (this.jogo.getPartida().getRodada().isFinalDaRodada()){
			notifyObservers("terminarRodada");
			this.jogo.getPartida().iniciarRodada();
			System.out.println("terminou rodada");
			notifyObservers("iniciarRodada",4000);
			return;
		}
	
		notifyObservers("atualizarJogadorDaVez");
		
	}

	public int getPosicaoJogadorDaVez() throws RemoteException {
		return this.jogo.getPartida().getRodada().getPosicaoJogadorDaVez();
	}

	public ObjCarta getUltimaCartaBaixada() throws RemoteException {
		return this.jogo.getPartida().getRodada().getUltimaCartaBaixada();
	}

	public int getNumeroDaRodadaAtual() throws RemoteException {
		return this.jogo.getPartida().getNumeroDaRodada();
	}
	
	@Override
	public int getEquipeVencedoraPartida() throws RemoteException {
		return this.jogo.getEquipeVencedoraPartidaAnterior();
	}

	@Override
	public int getEquipeVencedoraRodada() throws RemoteException {
		if (this.jogo.getPartida().getRodada().isEmpate())
			return -1;
		return this.jogo.getPartida().getRodada().getEquipeVencedora();
	}

	@Override
	public ObjCarta getMaiorCarta() throws RemoteException {
		return this.jogo.getPartida().getRodada().getMaiorCarta();
	}


	public void notifyObservers(String reference,int tempo) throws RemoteException {
		NotifyWithDelay notify = new NotifyWithDelay(this,reference,tempo);
		notify.start();
	}


	@Override
	public int getEquipeVencedoraJogo() throws RemoteException {
		return this.jogo.getEquipeVencedora();
	}

}

class NotifyWithDelay extends Thread {
	private JogoRemotoImpl jogoRemoto;
	private int tempo;
    private String reference;
    
    public NotifyWithDelay(JogoRemotoImpl jogoRemoto,String reference,int tempo) {
        this.jogoRemoto = jogoRemoto;
        this.tempo = tempo;
        this.reference = reference;
    }
    
    public void run()  {
        try {
            Thread.sleep(this.tempo);
            this.jogoRemoto.notifyObservers(this.reference);
        }
        catch(Exception e){};
    }
}